package com.simple.datax.db.service.impl;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.CannotCreateTransactionException;

import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.simple.datax.api.NeedResendSimpleException;
import com.simple.datax.api.SimpleException;
import com.simple.datax.core.model.connpara.CommonConnPara;
import com.simple.datax.db.mybatis.client.DataxEnterpriseChannelMapper;
import com.simple.datax.db.mybatis.client.DataxNodeChannelMapper;
import com.simple.datax.db.mybatis.client.DataxSendChannelMapper;
import com.simple.datax.db.mybatis.model.DataxEnterpriseChannel;
import com.simple.datax.db.mybatis.model.DataxEnterpriseChannelKey;
import com.simple.datax.db.mybatis.model.DataxNodeChannel;
import com.simple.datax.db.mybatis.model.DataxSendChannel;
import com.simple.datax.service.DBLoaderRouteService;
import com.simple.datax.service.SimpleDBException;

/**
 * @Title: DBLoaderRouterServiceImpl.java
 * @Package com.simple.datax.db.service.impl
 * @Description: TODO(添加描述)
 * @author Paladin Chen
 * @date 2012-12-28 上午11:04:35
 * @version V1.0
 */
@Service("dbRouteService")
public class DBLoaderRouterServiceImpl implements DBLoaderRouteService {
	private static final Logger logger = LoggerFactory.getLogger(DBLoaderRouterServiceImpl.class);

	@Autowired
	private DataxSendChannelMapper dscm;

	@Autowired
	private DataxEnterpriseChannelMapper decm;

	@Autowired
	private DataxNodeChannelMapper dncm;

	@Override
	public CommonConnPara getRouterInfoJoin(String receiver, String serviceCode) throws SimpleException {
		logger.debug("Begin to get Router Info...... receiver(" + receiver + ") serviceCode(" + serviceCode + ")");
		if (StringUtils.isBlank(receiver)) {
			throw new SimpleDBException("Receiver MUST NOT be blank!!!");
		} else {
			receiver = receiver.toUpperCase();
		}

		if (StringUtils.isBlank(serviceCode)) {
			serviceCode = "0";
		} else {
			serviceCode = serviceCode.toUpperCase();
		}
		DataxEnterpriseChannelKey decPK = new DataxEnterpriseChannelKey(receiver, serviceCode);
		
		DataxSendChannel dsc;
		String errmsg = String.format("Error Occur When get Enterprise(%s) Service(%s) Channel:", receiver,
				serviceCode);
		try {
			dsc = dscm.selectByJoinEnterprise(decPK);
		} catch (CannotGetJdbcConnectionException e) {
			throw new NeedResendSimpleException(errmsg, e);
		} catch (CannotCreateTransactionException e) {
			// TODO： 需要细分，目前统一重发
			throw new NeedResendSimpleException(errmsg, e);
		} catch (Exception e) {			
			// logger.error(errmsg, e);
			throw new SimpleDBException(errmsg, e);
		}

		if (dsc == null) {
			throw new SimpleDBException(String.format("Enterprise(%s) Service(%s) Channel is NOT Config or NOT Active", receiver,
					serviceCode));
		}
		
		CommonConnPara ccp = new CommonConnPara();

		ccp.setEncoding(dsc.getMsgCharset());
		ccp.setMsgFormat(dsc.getMsgFormat());
		ccp.setMsgType(dsc.getMsgType());
		ccp.setTransportPara(dsc.getCommunParam());
		ccp.setTransportType(dsc.getCommunType());
		return ccp;
	}

	/**
	 * 取企业某个服务的datax发送的地址
	 * 
	 * 对于没有拿到连接池的异常，将做重发处理
	 */
	@Override
	public CommonConnPara getRouterInfo(String receiver, String serviceCode) throws SimpleException {
		logger.debug("Begin to get Router Info...... receiver(" + receiver + ") serviceCode(" + serviceCode + ")");
		if (StringUtils.isBlank(receiver)) {
			throw new SimpleDBException("Receiver MUST NOT be blank!!!");
		} else {
			receiver = receiver.toUpperCase();
		}

		if (StringUtils.isBlank(serviceCode)) {
			serviceCode = "0";
		} else {
			serviceCode = serviceCode.toUpperCase();
		}

		DataxEnterpriseChannelKey decPK = new DataxEnterpriseChannelKey(receiver, serviceCode);

		DataxEnterpriseChannel dec;
		String errmsg = String.format("Error Occur When get Enterprise(%s) Service(%s) Channel:", receiver,
				serviceCode);
		try {
			dec = decm.selectByPrimaryKey(decPK);
		} catch (CannotGetJdbcConnectionException e) {
			throw new NeedResendSimpleException(errmsg, e);
		} catch (CannotCreateTransactionException e) {
			// TODO： 需要细分，目前统一重发
			throw new NeedResendSimpleException(errmsg, e);
		} catch (Exception e) {			
			// logger.error(errmsg, e);
			throw new SimpleDBException(errmsg, e);
		}

		if (dec != null) {
			if(dec.getFlag() != 1){
				throw new SimpleDBException(String.format("Enterprise(%s) Service(%s) Channel is NOT Active", receiver,
						serviceCode));
			}
			
			Long sendid = dec.getSysSendId();

			if (sendid == null) {
				throw new SimpleDBException(String.format("Enterprise(%s) Service(%s) Send Channel is NOT Config",
						receiver, serviceCode));
			}

			DataxSendChannel dsc;
			errmsg = String.format("Error Occur When get Enterprise(%s) Service(%s) Send Channel(%d):",
					receiver, serviceCode, sendid);
			try {
				dsc = dscm.selectByPrimaryKey(sendid);
			} catch (CannotGetJdbcConnectionException e) {
				throw new NeedResendSimpleException(errmsg, e);
			} catch (CannotCreateTransactionException e) {
				// TODO： 需要细分，目前统一重发
				throw new NeedResendSimpleException(errmsg, e);
			} catch (Exception e) {
				// logger.error(errmsg, e);
				throw new SimpleDBException(errmsg, e);
			}

			if (dsc == null) {
				throw new SimpleDBException(String.format("Enterprise(%s) Service(%s) Send Channel(%d) is NOT Config",
						receiver, serviceCode, sendid));
			}

			if(dsc.getFlag() != 1){
				throw new SimpleDBException(String.format("Enterprise(%s) Service(%s) Send Channel(%d) is NOT Active",
						receiver, serviceCode, sendid));
			}
			
			CommonConnPara ccp = new CommonConnPara();

			ccp.setEncoding(dsc.getMsgCharset());
			ccp.setMsgFormat(dsc.getMsgFormat());
			ccp.setMsgType(dsc.getMsgType());
			ccp.setTransportPara(dsc.getCommunParam());
			ccp.setTransportType(dsc.getCommunType());
			return ccp;
		} else {
			throw new SimpleDBException(String.format("Enterprise(%s) Service(%s) Channel is NOT EXIST", receiver,
					serviceCode));
		}
	}

	/**
	 * 取某个Node的接收地址（本node发送至目标地址）。
	 * 
	 * 对于没有拿到连接池的异常，将做重发处理
	 */
	@Override
	public CommonConnPara getNodeRouterInfo(String node) throws SimpleException {
		logger.debug("Begin to get Node Router Info ....node(" + node + ")");
		if (StringUtils.isBlank(node)) {
			throw new SimpleDBException("node MUST NOT be blank!!!");
		} else {
			node = node.toUpperCase();
		}

		DataxNodeChannel dnc;
		
		String errmsg = String.format("Error Occur When get node(%s) Channel:", node);
		try {
			dnc = dncm.selectByPrimaryKey(node);
		} catch (CannotGetJdbcConnectionException e) {
			throw new NeedResendSimpleException(errmsg, e);
		} catch (CannotCreateTransactionException e) {
			// TODO： 需要细分，目前统一重发
			throw new NeedResendSimpleException(errmsg, e);
		} catch (Exception e) {			
			// logger.error(errmsg, e);
			throw new SimpleDBException(errmsg, e);
		}

		if (dnc == null) {
			throw new SimpleDBException(String.format("Node(%s) Channel is NOT Config", node));
		}

		if(dnc.getFlag() != 1){
			throw new SimpleDBException(String.format("Node(%s) Channel is NOT Active!", node));
		}
		
		CommonConnPara ccp = new CommonConnPara();	

		ccp.setEncoding(dnc.getMsgCharset());
		ccp.setMsgFormat(dnc.getMsgFormat());
		ccp.setMsgType(dnc.getMsgType());
		ccp.setTransportPara(dnc.getCommunRecvParam());
		ccp.setTransportType(dnc.getCommunRecvType());
		return ccp;
	}
}
